/*
Pic Resizer : an easy to use program to resize your pictures
Copyright (C) 2009  Kévin Gomez <geek63@gmail.com>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "MainWindow.h"

MainWindow::MainWindow()
{
    //pour gérer l'utf8
    QTextCodec *charset = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForCStrings(charset);
    QTextCodec::setCodecForLocale(charset);
    QTextCodec::setCodecForTr(charset);

    //gestionnaire des profils
    manager = new ProfilesManager(QString(PROFILS_FILE));

    //création des actions
    createActions();
    //création des menus
    createMenus();
    //création de la toolbar
    createToolbar();
    //barre de status
    QStatusBar *status_bar = statusBar();
    status_bar->showMessage("Prêt");

    //création de la zone de "réception et d'affichage" de l'image
    image_label = new QLabel;
    image_label->setAlignment(Qt::AlignCenter);

    QScrollArea *zone_centrale = new QScrollArea(this);
    zone_centrale->setWidgetResizable(true);
    zone_centrale->setToolTip("Glissez ici une image");
    zone_centrale->setWidget(image_label);

    resize(500, 350);
    setWindowTitle("Pic Resizer");
    setWindowIcon(QIcon("./icons/picture.png"));
    setAcceptDrops(true);//pour le drag'n'drop

    setCentralWidget(zone_centrale);
}

void MainWindow::createActions()
{
    //quitter
    exit_act = new QAction(QIcon("./icons/exit.png"), tr("&Quitter"), this);
    exit_act->setShortcut(tr("Ctrl+Q"));
    exit_act->setStatusTip(tr("Quitte le programme"));
    connect(exit_act, SIGNAL(triggered()), qApp, SLOT(quit()));

    //ouvrir
    open_act = new QAction(QIcon("./icons/open.png"), tr("&Ouvrir une image"), this);
    open_act->setShortcut(tr("Ctrl+O"));
    open_act->setStatusTip(tr("Ouvre une image"));
    connect(open_act, SIGNAL(triggered()), this, SLOT(openDial()));

    //sauvegarder
    save_act = new QAction(QIcon("./icons/save.png"), tr("Enregi&strer"), this);
    save_act->setShortcut(tr("Ctrl+S"));
    save_act->setStatusTip(tr("Sauvegarde l'image actuelle et écrase la version originale"));
    connect(save_act, SIGNAL(triggered()), this, SLOT(save()));
    save_act->setDisabled(true);

    //sauvegarder
    save_as_act = new QAction(QIcon("./icons/save_as.png"),
                              tr("Enregistrer sous"), this);
    save_as_act->setStatusTip(tr("Sauvegarde l'image actuelle"));
    connect(save_as_act, SIGNAL(triggered()), this, SLOT(saveDial()));
    save_as_act->setDisabled(true);

    //miroir horizontal
    h_miror_act = new QAction(QIcon("./icons/h_miror.png"),
                              tr("Miroir &horizontal"), this);
    h_miror_act->setShortcut(tr("Ctrl+H"));
    h_miror_act->setStatusTip(tr("Faire pivoter l\'image autour d\'un axe horizontal"));
    connect(h_miror_act, SIGNAL(triggered()), this, SLOT(hMiror()));
    h_miror_act->setDisabled(true);

    //miroir vertical
    v_miror_act = new QAction(QIcon("./icons/v_miror.png"),
                              tr("Miroir &vertical"), this);
    v_miror_act->setShortcut(tr("Ctrl+V"));
    v_miror_act->setStatusTip(tr("Faire pivoter l\'image autour d\'un axe vertical"));
    connect(v_miror_act, SIGNAL(triggered()), this, SLOT(vMiror()));
    v_miror_act->setDisabled(true);

    //rotation vers la gauche
    l_rotate_act = new QAction(QIcon("./icons/l_rotate.png"),
                               tr("Faire pivoter vers la &gauche"), this);
    l_rotate_act->setShortcut(tr("Ctrl+G"));
    l_rotate_act->setStatusTip(tr("Faire pivoter l\'image de 90° vers la gauche"));
    connect(l_rotate_act, SIGNAL(triggered()), this, SLOT(rotateLeft()));
    l_rotate_act->setDisabled(true);

    //rotation vers la droite
    r_rotate_act = new QAction(QIcon("./icons/r_rotate.png"),
                               tr("Faire pivoter vers la &gdroite"), this);
    r_rotate_act->setShortcut(tr("Ctrl+D"));
    r_rotate_act->setStatusTip(tr("Faire pivoter l\'image de 90° vers la droite"));
    connect(r_rotate_act, SIGNAL(triggered()), this, SLOT(rotateRight()));
    r_rotate_act->setDisabled(true);

    //resize avatar (128 px)
    resize_avatar_act = new QAction(QIcon("./icons/resize_avatar.png"),
                                  tr("Redimensionner en tant qu'avatar"), this);
    resize_avatar_act->setStatusTip(tr("Redimensionne à la taille d'un avatar (128 px)"));
    connect(resize_avatar_act, SIGNAL(triggered()), this, SLOT(resizeAvatar()));
    resize_avatar_act->setDisabled(true);

    //resize perso
    resize_dial_act = new QAction(QIcon("./icons/resize.png"),
                                  tr("Redimensionnemment personnalisé"), this);
    resize_dial_act->setShortcut(tr("Ctrl+R"));
    resize_dial_act->setStatusTip(tr("Redimensionnemment personnalisé"));
    connect(resize_dial_act, SIGNAL(triggered()), this, SLOT(resizeDial()));
    resize_dial_act->setDisabled(true);

    profils_dial_act = new QAction(QIcon("./icons/profils_manager.png"),
                                   tr("Gérer les profils"), this);
    profils_dial_act->setShortcut(tr("Ctrl+P"));
    profils_dial_act->setStatusTip(tr("Ajouter/Modifier/Supprimer des profils"));
    connect(profils_dial_act, SIGNAL(triggered()), this, SLOT(profilsDial()));

    //resize perso via un profil
    profils_w = new QComboBox(this);
    fillProfilsList();
    resize_profil_act = new QAction(QIcon("./icons/go"),
                                    tr("Redimensionner selon ce profil"), this);
    //resize_profil_act->setShortcut(tr("Ctrl+P"));
    resize_profil_act->setStatusTip(tr("Profils de redimensionnement"));
    connect(resize_profil_act, SIGNAL(triggered()), this, SLOT(resizeProfil()));
    resize_profil_act->setDisabled(true);

    //on img drop
    connect(this, SIGNAL(imgDroped(QUrl)), this, SLOT(loadImage(QUrl)));

    connect(this, SIGNAL(imgLoaded()), this, SIGNAL(imgModified()));
    connect(this, SIGNAL(imgLoaded()), this, SLOT(enableActions()));

    //on actualisé l'image à chaque modification de cette dernière
    connect(this, SIGNAL(imgModified()), this, SLOT(imgToLabel()));
}

void MainWindow::enableActions()
{
    //save buttons
    save_act->setDisabled(false);
    save_as_act->setDisabled(false);

    //resize buttons
    resize_dial_act->setDisabled(false);
    resize_profil_act->setDisabled(false);
    resize_avatar_act->setDisabled((cur_image.height() < 128 and cur_image.width() < 128));

    //rotation buttons
    l_rotate_act->setDisabled(false);
    r_rotate_act->setDisabled(false);

    //miror buttons
    v_miror_act->setDisabled(false);
    h_miror_act->setDisabled(false);
}

void MainWindow::createToolbar()
{
    QToolBar *toolbar = addToolBar("Toolbar");

    toolbar->addAction(exit_act);
    toolbar->addSeparator();
    toolbar->addAction(open_act);
    toolbar->addAction(save_act);
    toolbar->addAction(save_as_act);
    toolbar->addSeparator();
    toolbar->addAction(h_miror_act);
    toolbar->addAction(v_miror_act);
    toolbar->addAction(l_rotate_act);
    toolbar->addAction(r_rotate_act);
    toolbar->addSeparator();
    toolbar->addAction(resize_avatar_act);
    toolbar->addAction(resize_dial_act);
    toolbar->addSeparator();
    toolbar->addWidget(profils_w);
    toolbar->addAction(resize_profil_act);
}

void MainWindow::createMenus()
{
    QMenuBar *menu_bar = menuBar();

    //création des menus
    QMenu *file_menu = menu_bar->addMenu(tr("&Fichier"));
    QMenu *img_menu = menu_bar->addMenu(tr("&Image"));
    QMenu *resize_menu = img_menu->addMenu(tr("&Redimensionner"));
    QMenu *rotate_menu = img_menu->addMenu(tr("&Tourner"));

    //remplissage des menus
    file_menu->addAction(open_act);
    file_menu->addSeparator();
    file_menu->addAction(save_act);
    file_menu->addAction(save_as_act);
    file_menu->addSeparator();
    file_menu->addAction(exit_act);

    resize_menu->addAction(resize_avatar_act);
    resize_menu->addAction(resize_dial_act);
    rotate_menu->addSeparator();
    resize_menu->addAction(profils_dial_act);

    rotate_menu->addAction(h_miror_act);
    rotate_menu->addAction(v_miror_act);
    rotate_menu->addSeparator();
    rotate_menu->addAction(l_rotate_act);
    rotate_menu->addAction(r_rotate_act);
}

void MainWindow::fillProfilsList()
{
    profils_w->clear();

    QList<Profil> list = manager->get();
    for (int i = 0; i < list.size(); ++i)
        profils_w->addItem(list.at(i).name);
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    event->acceptProposedAction();
}

void MainWindow::dropEvent(QDropEvent *event)
{
    event->acceptProposedAction();

    emit imgDroped(event->mimeData()->urls()[0]);
}

void MainWindow::loadImage(QUrl img_url)
{
    if(!org_image.load(img_url.toLocalFile()))
    {
        QMessageBox::StandardButton reply;
        reply = QMessageBox::information(this,
                 tr("Chargement du fichier impossible"),
                 tr("Impossible de charger ce fichier, vérifiez qu'il s'agit bien d'une image."));
    }
    else
    {
        cur_image = org_image;
        image_url = img_url.toLocalFile();

        emit imgLoaded();
    }
}

void MainWindow::imgToLabel()
{
    image_label->setPixmap(QPixmap::fromImage(cur_image));
}

void MainWindow::rotateLeft()
{
    rotate(-90);
}

void MainWindow::rotateRight()
{
    rotate(90);
}

void MainWindow::rotate(int angle)
{
    QTransform transform;
    transform.rotate(angle);

    cur_image = cur_image.transformed(transform);

    emit imgModified();
}

void MainWindow::hMiror()
{
    cur_image = cur_image.mirrored(false, true);

    emit imgModified();
}

void MainWindow::vMiror()
{
    cur_image = cur_image.mirrored(true, false);

    emit imgModified();
}

void MainWindow::openDial()
{
    QString file = QFileDialog::getOpenFileName(this, tr("Ouvrir une image"));

    if(!file.isNull())
        loadImage(file);
}

void MainWindow::save()
{
    cur_image.save(image_url);
}

void MainWindow::saveDial()
{
    QString old = image_url;

    image_url = QFileDialog::getSaveFileName(this, tr("Enregistrer l'image"),
                                             image_url);

    if(image_url.isNull())
        image_url = old;
    else
        cur_image.save(image_url);
}

void MainWindow::resizeDial()
{
    ResizeDial *dial = new ResizeDial(&org_image, &cur_image, this);
    connect(dial, SIGNAL(resized()), this, SIGNAL(imgModified()));

    dial->run();
}

void MainWindow::resizeAvatar()
{
    //avatar size :: 128x128
    cur_image = cur_image.scaled(128, 128, Qt::KeepAspectRatio,
                                 Qt::SmoothTransformation);

    emit imgModified();
}

void MainWindow::resizeProfil()
{
    Profil profil = manager->get(profils_w->currentText());

    if(!profil.save_proportions)
        cur_image = org_image.scaled(profil.width, profil.height);
    else
    {
        cur_image = (profil.width >= profil.height)
                     ? org_image.scaledToWidth(profil.width, Qt::SmoothTransformation)
                     : org_image.scaledToHeight(profil.height, Qt::SmoothTransformation);
    }

    emit imgModified();
}

void MainWindow::profilsDial()
{
    ProfilsManagerDial *dial = new ProfilsManagerDial(manager, this);

    connect(dial, SIGNAL(profilsModified()), this, SLOT(fillProfilsList()));

    dial->run();
}
